package com.prince.bean;

import static com.alibaba.fastjson.JSON.toJSON;
import static com.alibaba.fastjson.util.TypeUtils.castToBigDecimal;
import static com.alibaba.fastjson.util.TypeUtils.castToBigInteger;
import static com.alibaba.fastjson.util.TypeUtils.castToBoolean;
import static com.alibaba.fastjson.util.TypeUtils.castToByte;
import static com.alibaba.fastjson.util.TypeUtils.castToBytes;
import static com.alibaba.fastjson.util.TypeUtils.castToDate;
import static com.alibaba.fastjson.util.TypeUtils.castToDouble;
import static com.alibaba.fastjson.util.TypeUtils.castToFloat;
import static com.alibaba.fastjson.util.TypeUtils.castToInt;
import static com.alibaba.fastjson.util.TypeUtils.castToLong;
import static com.alibaba.fastjson.util.TypeUtils.castToShort;
import static com.alibaba.fastjson.util.TypeUtils.castToSqlDate;
import static com.alibaba.fastjson.util.TypeUtils.castToTimestamp;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.TypeUtils;
import com.prince.exception.EncException;
import com.prince.util.PayEncrypt;
import com.prince.util.StringUtil;

/**
 * JSONObject 包装类 ，params 永远不会为null 。为了规避以下问题： Spring
 * 默认注册了20多个ArgumentResolver，其中有匹配Map接口类型的ArgumentResolver，
 * 自定义ArgumentResolver的order无法指定。com.alibaba.fastjson.JSONObject
 * 实现了Map接口，会被MapMethodProcessor所抢先封参，造成java.lang.IllegalArgumentException:
 * 
 * @author lin
 *
 */
public class ResultParams {
	private final JSONObject params;

	public ResultParams() {
		super();
		params = new JSONObject();
	}

	public ResultParams(JSONObject params) {
		super();
		if (params != null) {
			this.params = params;
		} else {
			this.params = new JSONObject();
		}

	}

	public JSONObject getParams() {
		return params;
	}

	public ResultParams putKeyValue(String key, Object value) {
		params.put(key, value);
		return this;
	}

	public Object remove(String key) {
		if (this.params == null) {
			return null;
		}
		return this.params.remove(key);
	}

	public boolean isEmpty() {
		return params.isEmpty();
	}

	public boolean containsKey(Object key) {
		return params.containsKey(key);
	}

	public boolean containsValue(Object value) {
		return params.containsValue(value);
	}

	public Object get(Object key) {
		return params.get(key);
	}

	public JSONObject getJSONObject(String key) {
		Object value = params.get(key);

		if (value instanceof JSONObject) {
			return (JSONObject) value;
		}

		return (JSONObject) toJSON(value);
	}

	public JSONArray getJSONArray(String key) {
		Object value = params.get(key);

		if (value instanceof JSONArray) {
			return (JSONArray) value;
		}

		return (JSONArray) toJSON(value);
	}

	public <T> T getObject(String key, Class<T> clazz) {
		Object obj = params.get(key);
		return TypeUtils.castToJavaBean(obj, clazz);
	}

	public Boolean getBoolean(String key) {
		Object value = get(key);

		if (value == null) {
			return null;
		}

		return castToBoolean(value);
	}

	public byte[] getBytes(String key) {
		Object value = get(key);

		if (value == null) {
			return null;
		}

		return castToBytes(value);
	}

	public boolean getBooleanValue(String key) {
		Object value = get(key);

		if (value == null) {
			return false;
		}

		return castToBoolean(value).booleanValue();
	}

	public Byte getByte(String key) {
		Object value = get(key);

		return castToByte(value);
	}

	public byte getByteValue(String key) {
		Object value = get(key);

		if (value == null) {
			return 0;
		}

		return castToByte(value).byteValue();
	}

	public Short getShort(String key) {
		Object value = get(key);

		return castToShort(value);
	}

	public short getShortValue(String key) {
		Object value = get(key);

		if (value == null) {
			return 0;
		}

		return castToShort(value).shortValue();
	}

	public Integer getInteger(String key) {
		Object value = get(key);

		return castToInt(value);
	}

	public int getIntValue(String key) {
		Object value = get(key);

		if (value == null) {
			return 0;
		}

		return castToInt(value).intValue();
	}

	public Long getLong(String key) {
		Object value = get(key);

		return castToLong(value);
	}

	public long getLongValue(String key) {
		Object value = get(key);

		if (value == null) {
			return 0L;
		}

		return castToLong(value).longValue();
	}

	public Float getFloat(String key) {
		Object value = get(key);

		return castToFloat(value);
	}

	public float getFloatValue(String key) {
		Object value = get(key);

		if (value == null) {
			return 0F;
		}

		return castToFloat(value).floatValue();
	}

	public Double getDouble(String key) {
		Object value = get(key);

		return castToDouble(value);
	}

	public double getDoubleValue(String key) {
		Object value = get(key);

		if (value == null) {
			return 0D;
		}

		return castToDouble(value);
	}

	public BigDecimal getBigDecimal(String key) {
		Object value = get(key);

		return castToBigDecimal(value);
	}

	public BigInteger getBigInteger(String key) {
		Object value = get(key);

		return castToBigInteger(value);
	}

	public String getString(String key) {
		Object value = get(key);

		if (value == null) {
			return null;
		}

		return value.toString();
	}

	public Date getDate(String key) {
		Object value = get(key);

		return castToDate(value);
	}

	public java.sql.Date getSqlDate(String key) {
		Object value = get(key);

		return castToSqlDate(value);
	}

	public java.sql.Timestamp getTimestamp(String key) {
		Object value = get(key);

		return castToTimestamp(value);
	}

	public Object put(String key, Object value) {
		return params.put(key, value);
	}

	public void putAll(Map<? extends String, ? extends Object> m) {
		params.putAll(m);
	}

	public void clear() {
		params.clear();
	}

	public Object remove(Object key) {
		return params.remove(key);
	}

	public Set<String> keySet() {
		return params.keySet();
	}

	public Collection<Object> values() {
		return params.values();
	}

	public Set<Map.Entry<String, Object>> entrySet() {
		return params.entrySet();
	}

	@Override
	public String toString() {
		return params.toJSONString();
	}

	public Map<String, Object> toHashMap() {
		return JSONObjectToHashMap(params);
	}

	public Map<String, Object> toHashMapByPage(Object total,Object list) {
		params.put("total",total);
		params.put("rows", list);
		return JSONObjectToHashMap(params);
	}
	
	
	public String toJSONString(String error_code,String error_msg,String str) {
		try {
			str = PayEncrypt.encryptMode(str,JSON.toJSONString(params));
		} catch (EncException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return str;
	}
	
	public String toJSONString() {
		return JSON.toJSONString(params);
	}
	
	/**
	 * 加密
	 * @param str
	 * @param result
	 * @return
	 */
	public String toJSONString(String str,Map<String, String> result) {
		try {
			str = PayEncrypt.encryptMode(str,JSON.toJSONString(result));
		} catch (EncException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return str;
	}
	
	public String toJSONString(Object json) {
		return JSON.toJSONString(json);
	}
	
	
	public Map<String, Object> JSONObjectToHashMap(JSONObject params) {
		Map<String, Object> map = new HashMap<>();
		Set<String> keys = params.keySet();
		if (keys == null || keys.size() == 0) {
			return map;
		}
		Iterator<String> it = keys.iterator();
		while (it.hasNext()) {
			String key = it.next();
			Object value = params.get(key);
			if (value instanceof JSONObject) {
				value = JSONObjectToHashMap((JSONObject) value);
			}
			if (value instanceof JSONArray) {
				value = JSONArrayToArrayList((JSONArray) value);
			}
			map.put(key, value);
		}
		return map;
	}

	private Object JSONArrayToArrayList(JSONArray params) {
		List<Object> list = new ArrayList<>();
		for (int i = 0; i < params.size(); i++) {
			Object item = params.get(i);
			if (item instanceof JSONObject) {
				item = JSONObjectToHashMap((JSONObject) item);
			}
			if (item instanceof JSONArray) {
				item = JSONArrayToArrayList((JSONArray) item);
			}
			list.add(item);
		}
		return list;

	}
}
